<template>
  <page-content :center="true">
    <lz-form
      ref="form"
      :get-data="getData"
      :submit="onSubmit"
      :form.sync="form"
      :errors.sync="errors"
      :inDialog="true"
    >
      <lz-form-item 
        label="分类" 
        prop="category_id" 
        required
        :style="this.inLine33"
      >
        <a-select
          v-model="form.category_id"
          option-filter-prop="name"
          show-search
        >
          <a-select-option
            v-for="i of cates"
            :key="i.id"
            :name="i.name"
          >
            {{ i.name }}
          </a-select-option>
        </a-select>
      </lz-form-item>
      <lz-form-item 
        label="名称" 
        prop="name" 
        required
        :style="this.inLine33"
      >
        <a-input v-model="form.name"/>
      </lz-form-item>
      <lz-form-item 
        label="标识" 
        prop="slug" 
        required
        :style="this.inLine33"
      >
        <a-input v-model="form.slug"/>
      </lz-form-item>
      <lz-form-item 
        label="类型" 
        prop="type" 
        required
        :style="this.inLine50"
      >
        <a-select
          v-model="form.type"
          placeholder="类型"
          allow-clear
          show-search
          option-filter-prop="name"
        >
          <a-select-option
            v-for="i of types"
            :key="i.value"
            :name="i.label"
          >
            {{ i.label }}
          </a-select-option>
        </a-select>
      </lz-form-item>
      <lz-form-item 
        label="简介" 
        prop="desc"
        :style="this.inLine50"
      >
        <a-input v-model="form.desc" type="input"/>
      </lz-form-item>
      <lz-form-item 
        label="选项" 
        prop="options"
      >
        <type-options  v-model="form.options" :type="form.type"/>
      </lz-form-item>
      <lz-form-item 
        label="默认值" 
        prop="value"
        :tip="`表单的默认值`"
      >
        <type-input
          v-model="form.value"
          :type="form.type"
          :options="form.options"
          :config_options="config_options"
        />
      </lz-form-item>

      <lz-form-item 
        label="表单验证规则" 
        prop="validation_rules" 
      >
        <a-table 
          :row-selection="rowSelection" 
          rowKey="key"
          :columns="columns" 
          :data-source="validation_rules"
          :expandIconAsCell="false" 
          :expandIconColumnIndex="1"
          :pagination="true"
          size="small"
          bordered
        >
          <div
            slot="filterDropdown"
            slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"
            style="padding: 4px"
          >
            <a-input
              v-ant-ref="c => (searchInput = c)"
              :placeholder="`${column.title}`"
              :value="selectedKeys[0]"
              style="width: 114px; margin-bottom: 4px; display: block;"
              @change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
              @pressEnter="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
            />
            <a-button
              type="primary"
              size="small"
              style="width: 55px; margin-right: 4px"
              @click="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
            >
              搜索
            </a-button>
            <a-button size="small" style="width: 55px" @click="() => handleReset(clearFilters)">
              重置
            </a-button>
          </div>
          <a-icon
            slot="filterIcon"
            slot-scope="filtered"
            type="search"
            :style="{ color: filtered ? '#108ee9' : undefined }"
          />
          <template slot="customRender" slot-scope="text, record, index, column">
            <span v-if="searchText && searchedColumn === column.dataIndex">
              <template
                v-for="(fragment, i) in text
                  .toString()
                  .split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))"
              >
                <mark
                  v-if="fragment.toLowerCase() === searchText.toLowerCase()"
                  :key="i"
                  class="highlight"
                  >{{ fragment }}</mark
                >
                <template v-else>{{ fragment }}</template>
              </template>
            </span>
            <template v-else>
              {{ text }}
            </template>
          </template>
          <template slot="param0_value" slot-scope="text,record">
            <template v-if="record.param0_key">
              <editable-cell 
                :text="text" 
                :placeholder="record.param0_key" 
                @change="onCellChange(record.key, 'param0_value', $event)" 
                v-model="validation_params[record.key][0]"
              />
            </template>
          </template>
          <template slot="param1_value" slot-scope="text,record">
            <template v-if="record.param1_key">
              <editable-cell 
                :text="text" 
                :placeholder="record.param1_key" 
                @change="onCellChange(record.key, 'param1_value', $event)" 
                v-model="validation_params[record.key][1]"
              />
            </template>
          </template>
        </a-table>
      </lz-form-item>
      <lz-form-item 
        label="排序" 
        prop="order"
        :style="this.inLine50"
      >
        <a-input-number :min="-9999" :max="9999" v-model="form.order"/>
      </lz-form-item>
      <lz-form-item 
        label="表单输入框是否禁用" 
        prop="form_disabled"
        :style="this.inLine50"
      >
        <a-switch v-model="form.form_disabled"/>
      </lz-form-item>
    </lz-form>
    <div>
      <a-anchor
        :affix="true"
        :get-current-anchor="getCurrentAnchor"
        :target-offset="targetOffset"
      >
        <a-anchor-link 
          v-for="config of configs" 
          :href="`#/configs/${config.id}/edit`" 
          :title="`${config.name}:${config.slug}`"
        />
      </a-anchor>
    </div>
  </page-content>
</template>

<script>
const columns = [
  {
    title: '验证规则',
    dataIndex: 'key',
    scopedSlots: { customRender: 'key' },
    scopedSlots: {
      filterDropdown: 'filterDropdown',
      filterIcon: 'filterIcon',
      customRender: 'customRender',
    },
    onFilter: (value, record) =>
      record.key
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => {
          this.searchInput.focus();
        }, 0);
      }
    },
  },
  {
    title: '描述',
    dataIndex: 'description',
    scopedSlots: { customRender: 'description' },
    scopedSlots: {
      filterDropdown: 'filterDropdown',
      filterIcon: 'filterIcon',
      customRender: 'customRender',
    },
    onFilter: (value, record) =>
      record.description
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => {
          this.searchInput.focus();
        }, 0);
      }
    },
  },
  {
    title: '参数一',
    dataIndex: 'param0_value',
    scopedSlots: { customRender: 'param0_value' },
  },
  {
    title: '参数二',
    dataIndex: 'param1_value',
    scopedSlots: { customRender: 'param1_value' },
  }
];

import LzForm from '@c/LzForm'
import { mapConstants } from '@/libs/constants'
import {
  createConfig,
  editConfig,
  storeConfig,
  updateConfig,
  getParseOptions
} from '@/api/configs'
import {
  inArray,
} from '@/libs/utils'
import _forIn from 'lodash/forIn'
import TypeOptions from './components/TypeOptions'
import TypeInput from './components/TypeInput'
import { toInt } from '@/libs/utils'
import PageContent from '@c/PageContent'
import LzFormItem from '@c/LzForm/LzFormItem'
import EditableCell from '@c/EditableCell'

export default {
  name: 'Form',
  components: {
    LzFormItem,
    PageContent,
    TypeInput,
    TypeOptions,
    LzForm,
    EditableCell
  },
  data() {
    return {
      form: {
        type: '',
        category_id: '',
        name: '',
        slug: '',
        desc: '',
        options: {},
        value: '',
        validation_rules: [],
        form_disabled: false,
        order: 0,
      },

      configs: [],
      errors: {},
      types: [],
      cates: [],
      config_options: {},
      validation_rules: [],
      validation_params: {"accepted":[],"active_url":[],"after":[],"after_or_equal":[],"alpha":[],"alpha_dash":[],"alpha_num":[],"array":[],"before":[],"before_or_equal":[],"between":[],"boolean":[],"confirmed":[],"date":[],"date_equals":[],"date_format":[],"different":[],"digits":[],"digits_between":[],"dimensions":[],"distinct":[],"email":[],"ends_with":[],"exists":[],"file":[],"filled":[],"gt":[],"gte":[],"image":[],"in":[],"in_array":[],"integer":[],"ip":[],"ipv4":[],"ipv6":[],"json":[],"lt":[],"lte":[],"max":[],"mimes":[],"mimetypes":[],"min":[],"not_in":[],"not_regex":[],"numeric":[],"password":[],"present":[],"regex":[],"required":[],"required_if":[],"required_unless":[],"required_with":[],"required_with_all":[],"required_without":[],"required_without_all":[],"same":[],"size":[],"starts_with":[],"string":[],"timezone":[],"unique":[],"uploaded":[],"url":[],"uuid":[]},
      columns,
      selectedRowKeys: [],
      inLine33: {
        display: 'inline-block',
        width: '33%'
      },
      inLine50: {
        display: 'inline-block',
        width: '50%'
      },
      targetOffset: undefined,
      searchText: '',
      searchInput: null,
      searchedColumn: '',
    }
  },
  created() {
    
  },
  computed: {
    ...mapConstants(['CONFIG_TYPES']),
    rowSelection() {
      return {
        onChange: (selectedRowKeys) => {
          this.selectedRowKeys = selectedRowKeys
        },
        getCheckboxProps: record => {
          return {
            props: {
              defaultChecked: this.selectedRowKeys.includes(record.key)
            }
          };
        }
      };
    },
  },
  methods: {
    handleSearch(selectedKeys, confirm, dataIndex) {
      confirm();
      this.searchText = selectedKeys[0];
      this.searchedColumn = dataIndex;
    },
    handleReset(clearFilters) {
      clearFilters();
      this.searchText = '';
    },
    getCurrentAnchor() {
      return '#/configs/'+this.$route.params.id+'/edit';
    },
    onCellChange(key, dataIndex, value) {
      const validation_rules = [...this.validation_rules];
      const target = validation_rules.find(item => item.key === key);
      if (target) {
        target[dataIndex] = value;
        this.validation_rules = validation_rules;
      }
    },
    async getData($form) {
      let data
      let attribute = this.form.slug

      if ($form.realEditMode) {
        ({ data } = await editConfig($form.resourceId))
        // 验证规则
        this.selectedRowKeys = [];
        if ( data.data.validation_rules ) {
          const validationRules = data.data.validation_rules.split('|')
          validationRules.forEach((validationRule) => {
            const validationRuleArr = validationRule.split(':')
            // 回显选择框
            this.selectedRowKeys.push(validationRuleArr[0])
          })
        }
        // 字段标识
        attribute = data.data.slug
        // 所有配置
        this.configs = data.data.configs

        const options = await getParseOptions({
          type:data.data.type,
          options:data.data.options,
          scene:'form',
        })

        this.config_options = options.data.options
      } else {
        ({ data } = await createConfig())
      }

      this.cates = data.categories

      const types = []
      _forIn(data.types_map, (value, key) => {
        types.push({
          value: key,
          label: value,
        })
      })
      this.types = types
      // 表单中类型，默认选择第一个
      this.form.type = types[0].value
      
      data.validation_rules_map.forEach((i) => {
        i.description = i.description.replace(':attribute', attribute)
        // 回显参数值
        if (i.param0_value) {
          this.validation_params[i.key][0] = i.param0_value
        }
        if (i.param1_value) {
          this.validation_params[i.key][1] = i.param1_value
        }
      })
      this.validation_rules = data.validation_rules_map
      
      !this.editMode && (this.form.category_id = toInt(this.$route.query.category_id, ''))
      return data.data
    },
    async onSubmit($form) {
      const selectedRowKeys = this.selectedRowKeys.toString().split(',')
      const validationParamKeys = []
      const validationRules = [];
      _forIn(this.validation_params, (value, key) => {
        if (inArray(key,selectedRowKeys) && value.length>0) {
          validationRules.push(key+':'+value.join(','))
          validationParamKeys.push(key)
        }
      })
      _forIn(selectedRowKeys, (value) => {
        if (!inArray(value,validationParamKeys)) {
          validationRules.push(value)
        }
      })
      this.form.validation_rules = validationRules.join('|')
      if ($form.realEditMode) {
        await updateConfig($form.resourceId, this.form)
      } else {
        await storeConfig(this.form)
      }
    },
  },
}
</script>
<style>
.highlight {
  background-color: rgb(255, 192, 105);
  padding: 0px;
}
.ant-anchor-wrapper {
  margin-left: 30px;
}
</style>